package adminService

import (
	"fmt"
	"gin-gorm-oj/define"
	"gin-gorm-oj/models"
	"gin-gorm-oj/redis"
	"gin-gorm-oj/response"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type DishVO struct {
	Id           int                  `gorm:"column:id;type:int(11);" json:"id"`
	Name         string               `gorm:"column:name;type:varchar(32);" json:"name"`
	Price        float64              `gorm:"column:price;type:decimal(10,2);" json:"price"`
	CategoryId   int                  `gorm:"column:category_id;type:int(11);" json:"categoryId"`
	Status       *int                 `gorm:"column:status;type:int(2);" json:"status"`
	Description  string               `gorm:"column:description;type:varchar(255);" json:"description"`
	Image        string               `gorm:"column:image;type:varchar(255);" json:"image"`
	Flavors      []*models.DishFlavor `gorm:"foreignKey:dish_id;references:id"  json:"flavors"`
	UpdatedAt    time.Time            `gorm:"column:updated_at;type:datetime;" json:"updateTime"`
	CategoryName string               `gorm:"column:category_name;type:varchar(32);" json:"categoryName"`
}

func AddDish(c *gin.Context) {
	var dish models.Dish
	err := c.ShouldBindBodyWithJSON(&dish)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	dish.Status = &define.DEFAULT_STATUS_ENABLE

	err = models.Db.Create(&dish).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "服务器错误",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "添加成功",
		"data": dish,
	})
	return

}

func DishPageList(c *gin.Context) {
	fmt.Println("1234")
	name := c.Query("name")
	page, err := strconv.Atoi(c.DefaultQuery("page", define.DefaultPage))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", define.DefaultSize))
	categoryId, _ := strconv.Atoi(c.Query("category_id"))
	statusStr := c.Query("status")
	status := -1
	if statusStr != "" {
		status, _ = strconv.Atoi(statusStr)
	}
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	page = (page - 1) * pageSize
	var total int64
	var dishVO []*DishVO

	db := models.Db.Model(new(models.Dish)).
		Table("dish d").
		Select("d.*, c.name as category_name").
		Joins("left join category c on d.category_id = c.id")
	if name != "" {
		db = db.Where("d.name like ?", "%"+name+"%")
	}
	if status != -1 {
		db = db.Where("d.status = ?", status)
	}
	if categoryId != 0 {
		db = db.Where("d.category_id = ?", categoryId)
	}
	db.Count(&total)
	db.Offset(page).Limit(pageSize).Order("d.updated_at desc").Find(&dishVO)

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": gin.H{
			"total":   total,
			"records": dishVO,
		},
	})

}

func DeleteDish(c *gin.Context) {
	idsParam := c.Query("ids")
	idsStrings := strings.Split(idsParam, ",")
	var ids []int64
	for _, id := range idsStrings {
		idInt, _ := strconv.Atoi(id)
		ids = append(ids, int64(idInt))
	}
	err := models.Db.Where("id in (?)", ids).Delete(&models.Dish{}).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "服务器错误",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "删除成功",
	})

}

func GetDishById(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var dishVO DishVO
	var dish models.Dish
	err := models.Db.Where("id = ?", id).First(&dish).Error
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "服务器错误",
		})
		return
	}
	models.Db.Raw(
		"select d.*,c.name category_name "+
			"from dish d "+
			"left join category c on c.id = d.category_id"+
			" where d.id = ?", id).Scan(&dishVO)
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": dishVO,
	})
}

func GetDishByCategoryId(c *gin.Context) {
	categoryId, err := strconv.Atoi(c.Query("categoryId"))
	if err != nil {
		response.ResponseBadRequest(c)
		return
	}

	categoryIdStr := c.Query("categoryId")
	key := "dish_" + categoryIdStr
	var dishVO []*DishVO
	err = redis.Get(key, &dishVO)
	if err == nil {
		response.ResponseOK(c, dishVO)
		return
	}

	var category models.Category
	err = models.Db.Where("id = ?", categoryId).Find(&category).Error
	if err != nil {
		response.ResponseInternalServerError(c)
		return
	}
	db := models.Db.Model(new(models.Dish)).
		Table("dish d").
		Select("d.*,c.name category_name").
		Joins("left join category c on d.category_id = c.id").
		Preload("Flavors")
	err = db.Where("category_id = ?", categoryId).Find(&dishVO).Error
	if err != nil {
		response.ResponseInternalServerError(c)
		return
	}
	response.ResponseOK(c, dishVO)
	redis.Set(key, dishVO)

	return
}

func UpdateDish(c *gin.Context) {
	var dish models.Dish
	err := c.ShouldBindBodyWithJSON(&dish)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	if dish.Status != nil {
		err := models.Db.Where("id = ?", dish.Id).Update("status", dish.Status).Error
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 400,
				"msg":  "参数错误",
			})
			return
		}

	}
	err = models.Db.Where("id = ?", dish.Id).Updates(&dish).Error
	models.Db.Where("id = ?")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "服务器错误",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "Update Success",
	})

}

func UpdateDishStatus(c *gin.Context) {
	status, err := strconv.Atoi(c.Param("status"))
	id, _ := strconv.Atoi(c.Query("id"))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	models.Db.Model(new(models.Dish)).Where("id = ?", id).Update("status", status)
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "Update Success",
	})

}
